package main

import "fmt"

/*
1、在Go语言中函数可以作为变量、参数传递，也可也作为返回值返回
*/

func add6(a, b int) int {
	sum := a + b
	return sum
}

/*
2、函数可以作为变量、参数传递
*/
func add7(f func(a, b int) int, a, b int) int {
	// 此时可以就看入参为一个函数
	fmt.Println("函数作为入参传递")
	//调用传入进来的函数
	k := f(a, b)
	return k
}

/*
3、函数作为返回值，并且定义匿名函数(匿名函数是一种没有指定函数名的函数声明方式)
*/

// 在这个函数中的返回值是函数
func add8(opt string) func(a, b int) int {
	switch opt {
	case "add":
		//返回定义的匿名函数
		return func(a, b int) int {
			return a + b
		}
	case "del":
		//返回定义的匿名函数
		return func(a, b int) int {
			return a - b
		}
	default:
		//返回定义的匿名函数
		return func(a, b int) int {
			return a + b
		}
	}
}

func main() {
	//函数作为变量传递给sumFucc，此时sumFucc拥有add6函数的功能，主要传递的时候不能带()，只能写函数名，带()就是直接调用函数
	sumFucc := add6
	fmt.Println("sum is", sumFucc(1, 3))

	//调用函数作为入参的函数
	//上面函数在作为入参传递的时候也只能写函数名，不能带()，add7(add6(1,2))该写法报错了，所有才对add7函数定义了三个入参，一个为函数，另外两个作为入参函数的入参
	result := add7(add6, 1, 3)
	fmt.Println("result is", result)

	//在这里通过匿名函数定义了一个临时函数传入
	result2 := add7(func(a, b int) int {
		return a - b
	}, 8, 9)
	fmt.Println("result2 is", result2)

	//调用返回值为参数的函数
	sumFunc1 := add8("add")                    //用变量接收函数
	fmt.Println("sumFunc1 is", sumFunc1(1, 2)) //调用返回值函数
}
